#ifndef VIRTIO_H
#define VIRTIO_H

#include "iomem.h"

typedef struct {
    PhysMemoryMap *mem_map;
    uint64_t addr;
    IRQSignal *irq;
} VIRTIOBusDef;

typedef uint64_t virtio_phys_addr_t;

typedef struct VIRTIODevice VIRTIODevice;

typedef struct BlockDevice BlockDevice;

typedef struct CharacterDevice CharacterDevice;

struct BlockDevice {
    #define SECTOR_SIZE 512
    void *opaque;
    int64_t (*get_sector_count) (void *opaque);
    int (*read_sector) (void *opaque, uint64_t sector_num, uint8_t *buf, int n);
    int (*write_sector) (void *opaque, uint64_t sector_num, const uint8_t *buf, int n);
};

struct CharacterDevice {
    void *opaque;
    void (*write_data)(void *opaque, const uint8_t *buf, int len);
    int (*read_data)(void *opaque, uint8_t *buf, int len);
};

VIRTIODevice *virtio_block_init (VIRTIOBusDef *bus, BlockDevice *bs);
VIRTIODevice *virtio_console_init (VIRTIOBusDef *bus, CharacterDevice *cs);
BOOL virtio_console_can_write_data (VIRTIODevice *s);
int virtio_console_get_write_len (VIRTIODevice *s);
int virtio_console_write_data (VIRTIODevice *s, uint8_t *buf, int buf_len);

#endif